const { spawn } = require('child_process')
const path = require('path')

/**
 * 获取视频元数据
 * @param {string} filePath 视频文件路径
 * @param {string} ffpath ffmpeg bin路径
 * @returns {Promise<Object>} 包含视频元数据的 Promise 对象
 */

function getFramesLenth(filePath, cmdPath, debug = null) {
    return new Promise((resolve, reject) => {
        const args = [
            '-v', 'error',
            '-select_streams', 'v:0',      // 只处理第一个视频流
            '-show_entries', 'stream=nb_read_frames', // 强制统计帧数
            '-count_frames',               // 实际计数
            '-of', 'default=nokey=1:noprint_wrappers=1',
            filePath
        ]

        if (debug) console.log(cmdPath.ffprobe + ' ' + args.join(' '))
        const ffprobe = spawn(cmdPath.ffprobe, args)


        // 收集输出数据
        let stdoutChunks = []
        let stderrChunks = []

        // 捕获标准输出
        ffprobe.stdout.on('data', chunk => {
            stdoutChunks.push(chunk)
        })

        // 捕获错误输出
        ffprobe.stderr.on('data', chunk => {
            stderrChunks.push(chunk)
        })

        // 处理进程错误（如文件不存在）
        ffprobe.on('error', err => {
            reject(new Error(`执行失败: ${err.message}`))
        })

        // 处理进程退出
        ffprobe.on('close', code => {
            if (code !== 0) {
                const errorMessage = Buffer.concat(stderrChunks).toString()
                reject(new Error(`FFprobe 退出码 ${code}: ${errorMessage}`))
                return
            }

            try {
                resolve(Buffer.concat(stdoutChunks).toString())

            } catch (e) {
                reject(new Error(`JSON 解析失败: ${e.message}`))
            }
        })
    })
}


function getMediaMeta(filePath, cmdPath, debug = null) {
    return new Promise((resolve, reject) => {
        // 构建 ffprobe 参数
        const args = [
            '-v', 'error',          // 只显示错误信息
            '-show_format',         // 显示容器格式信息
            '-show_streams',        // 显示流信息
            '-print_format', 'json', // 输出为 JSON 格式
            filePath                // 文件路径（最后一个参数）
        ]

        if (debug) console.log(cmdPath.ffprobe + ' ' + args.join(' '))
        // 创建子进程
        const ffprobe = spawn(cmdPath.ffprobe, args)

        // 收集输出数据
        let stdoutChunks = []
        let stderrChunks = []

        // 捕获标准输出
        ffprobe.stdout.on('data', chunk => {
            stdoutChunks.push(chunk)
        })

        // 捕获错误输出
        ffprobe.stderr.on('data', chunk => {
            stderrChunks.push(chunk)
        })

        // 处理进程错误（如文件不存在）
        ffprobe.on('error', err => {
            reject(new Error(`执行失败: ${err.message}`))
        })

        // 处理进程退出
        ffprobe.on('close', code => {
            if (code !== 0) {
                const errorMessage = Buffer.concat(stderrChunks).toString()
                reject(new Error(`FFprobe 退出码 ${code}: ${errorMessage}`))
                return
            }

            try {
                // 解析 JSON 结果
                const output = Buffer.concat(stdoutChunks).toString()
                const metadata = JSON.parse(output)
                resolve(metadata)
            } catch (e) {
                reject(new Error(`JSON 解析失败: ${e.message}`))
            }
        })
    })
}

// 获取视频第一帧并返回 Buffer
function getFrames(filePath, cmdPath, start, debug) {
    return new Promise((resolve, reject) => {
        let chunks = [];

        const args = [
            '-v', 'error',
            '-ss', '0',
            '-i', filePath,         // 输入文件
            '-vf', `select=eq(n\\,${start})`,
            '-vframes', '1',         // 只提取一帧
            '-f', 'image2pipe',      // 输出格式为管道（适合流式传输）
            '-c:v', 'mjpeg',         // 使用 MJPEG 编码
            // '-c:v', 'png',
            '-'                      // 输出到标准输出
        ]

        // 使用 FFmpeg 提取第一帧
        const ffmpeg = spawn(cmdPath.ffmpeg, args)

        // 监听子进程的标准输出流
        ffmpeg.stdout.on('data', (chunk) => {
            chunks.push(chunk); // 收集所有数据块
        })

        // 监听错误事件
        ffmpeg.stderr.on('data', (data) => {
            console.error(`FFmpeg 错误: ${data.toString()}`);
        })

        // 子进程结束时的处理
        ffmpeg.on('close', (code) => {
            if (code === 0) {
                const buffer = Buffer.concat(chunks); // 将所有数据块合并成一个 Buffer
                resolve(`${start}-data:image/png;base64,${buffer.toString('base64')}`)
            } else {
                reject(new Error(`FFmpeg 进程退出，状态码: ${code}`))
            }
        })

        // 如果子进程启动失败
        ffmpeg.on('error', (err) => {
            reject(err);
        })
    })
}


module.exports = { getMediaMeta, getFramesLenth, getFrames }


// const ffpath = 'E:/MyProject/js脚本/git/ffmpegTEST/internal/ffmpeg'
// const videoPath = 'C:/Users/haha/Videos/obs/123.ts'

// getMediaMeta(videoPath, ffpath)
//     .then(metadata => {
//         console.log(metadata)
//     })
//     .catch(err => {
//         console.error(err);
//     })